/*
 * Author: vyouzhi <vyouzhi@163.com>
 * http://www.xda.cn
 *
 * File: epoll_lib.c
 * Create Date: 2011-08-05 20:20:58
 *
 */
#include <sys/epoll.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include "epoll_lib.h"
#include "conf_lib.h"
#include "socket_lib.h"
#include "thread_lib.h"


int Epoll_Init(void){
	struct epoll_event ev;
	struct epoll_event events[MAXEPOLLS];
	CThread_param *cthread_param;
	int s, efd, e_num, i, accept_fd, m_sockfd;
	struct sockaddr_in client;
	socklen_t len = sizeof(client);	

	
	m_sockfd = Socket_Init();
	if(m_sockfd == -1)exit(-1);

	efd = epoll_create(MAXEPOLLS);
	
	if (efd == -1){
      	printf("epoll_create error !\n");
		return (-1);
    }

	ev.data.fd = m_sockfd;
	ev.events = EPOLLIN ;
  	s = epoll_ctl(efd, EPOLL_CTL_ADD, m_sockfd, &ev);
	if (s == -1){
	      printf("epoll_ctl error !\n");
      	  return (-1);
    }
	
	while(1){
		e_num = epoll_wait(efd, events, MAXEVENTS, -1);
		if(e_num == -1) {
			printf("epoll_wait error !\n");
			exit(-1);
		}
		for(i=0; i<e_num; i++){
			if(events[i].data.fd == m_sockfd){
				accept_fd = accept(m_sockfd, (struct sockaddr *)&client, &len) ;
				if(accept_fd < 0)
				{
					ev.events = EPOLLOUT;
					ev.data.fd = events[i].data.fd;
					epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
					events[i].data.fd = -1;
					printf("accetp error\r\n");
					continue;
				}
			/*	SetNonBlocking(accept_fd);*/
				ev.events = EPOLLIN ;
				ev.data.fd = accept_fd;
				if(epoll_ctl(efd, EPOLL_CTL_ADD, accept_fd, &ev) < 0)
				{
					printf("epoll add error\r\n");
					return (-1);
				}
			}else if(events[i].events & EPOLLIN){
				ev.events = EPOLLOUT ;
				ev.data.fd = events[i].data.fd;
				epoll_ctl(efd, EPOLL_CTL_MOD, events[i].data.fd, &ev);

				cthread_param = (CThread_param *)malloc(sizeof(CThread_param));
				cthread_param->client_fd = &(events[i].data.fd);
				cthread_param->event = &ev;
				Thread_Init(efd, cthread_param);	
			}

		}

	}
	close(m_sockfd);
	return 0;	
}


/*
void Epoll_End(CThread_param *eparm){
	int efd, cfd, s;	
	struct epoll_event *event;
	
	efd = *(eparm->sock_fd);
	cfd = *(eparm->client_fd);
	event = eparm->event;
	s = epoll_ctl(efd, EPOLL_CTL_DEL, cfd, event);
	if(-1 == s){
		printf("epoll_ctl error EPOLL_CTL_DEL\n");
		return (-1);
	}
	free(eparm);
	close(cfd);
}*/
/* vim: set ts=4 sw=4: */

